/*
 * activity.h
 *
 *  Created on: 10 Şub 2012
 *      Author: root
 */

#ifndef ACTIVITY_H_
#define ACTIVITY_H_


#include "and_config.h"
#include "messaging/message.h"
#include "messaging/messaging_abstract.h"
#include "messaging/activity/message_activity_config_changed.h"
#include "messaging/activity/message_activity_gained_focus.h"
#include "messaging/activity/message_activity_init_window.h"
#include "messaging/activity/message_activity_lost_focus.h"
#include "messaging/activity/message_activity_content_rect_changed.h"
#include "messaging/activity/message_activity_input_changed.h"
#include "messaging/activity/message_activity_low_memory.h"
#include "messaging/activity/message_activity_pause.h"
#include "messaging/activity/message_activity_resume.h"
#include "messaging/activity/message_activity_save_state.h"
#include "messaging/activity/message_activity_destroy.h"
#include "messaging/activity/message_activity_start.h"
#include "messaging/activity/message_activity_stop.h"
#include "messaging/activity/message_activity_term_window.h"
#include "messaging/activity/message_activity_window_redraw_needed.h"
#include "messaging/activity/message_activity_window_resized.h"

#include "input/input_handler.h"
#include "input/event/motion_event.h"

#include <android/configuration.h>
#include <android/looper.h>
#include <android/native_activity.h>


#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>


extern int  android_main();
namespace androidplus {


class activity  {
public:
	activity();
	virtual ~activity();


//friend functions
public:
    friend void * threading_entry(void *arg);
    friend void activityOnStart(ANativeActivity* activity);
    friend void activityOnResume(ANativeActivity* activity);
    friend void activityOnPause(ANativeActivity* activity);
    friend void activityOnStop(ANativeActivity* activity);
    friend void* activityOnSaveInstanceState(ANativeActivity* activity, size_t* outSize);
    friend void activityOnDestroy(ANativeActivity* activity);
    friend void activityOnNativeWindowCreated(ANativeActivity* activity,ANativeWindow* window);
    friend void activityOnWindowFocusChanged(ANativeActivity* activity, int hasFocus);
    friend void activityOnNativeWindowResized(ANativeActivity* activity,ANativeWindow* window);
    friend void activityOnNativeWindowRedrawNeeded(ANativeActivity* activity,ANativeWindow* window);
    friend void activityOnNativeWindowDestroyed(ANativeActivity* activity,ANativeWindow* window);
    friend void activityOnContentRectChanged(ANativeActivity* activity, const ARect* rect);
    friend void activityOnInputQueueCreated(ANativeActivity* activity, AInputQueue* queue);
    friend void activityOnInputQueueDestroyed(ANativeActivity* activity,AInputQueue* queue);
    friend void activityOnConfigurationChanged(ANativeActivity* activity);
    friend void activityOnLowMemory(ANativeActivity* activity);
public:
    void init(ANativeActivity* activity, void* savedState,size_t savedStateSize);

//friend classes
public:
    friend class application;
    friend class messaging::message;
    friend class messaging::activity::message_activity_start;
    friend class messaging::activity::message_activity_stop;
    friend class messaging::activity::message_activity_resume;
    friend class messaging::activity::message_activity_pause;
    friend class messaging::activity::message_activity_destroy;
    friend class messaging::activity::message_activity_config_changed;
    friend class messaging::activity::message_activity_init_window;
    friend class messaging::activity::message_activity_gained_focus;
    friend class messaging::activity::message_activity_lost_focus;
    friend class messaging::activity::message_activity_window_redraw_needed;
    friend class messaging::activity::message_activity_window_resized;
    friend class messaging::activity::message_activity_term_window;
    friend class messaging::activity::message_activity_content_rect_changed;
    friend class messaging::activity::message_activity_input_changed;
    friend class messaging::activity::message_activity_save_state;
    friend class eventwatcher;



public:
		and_config * cur_conf();
public:


public:
		 enum ACTIVITY_STATE
		        {
		        	ACTIVITY_RUNNING,
		        	ACTIVITY_STOPED,
		        	ACTIVITY_DESTROYED,
		        	ACTIVITY_PAUSED
		        };
		    int state() const;

protected:
		     ANativeWindow * cur_native_window();

protected:
	        void on_start();
		    void on_resume();
			void on_pause();
			void on_stop();
			void on_configuration_changed();
			void on_native_window_created(ANativeWindow* window);
			void on_native_window_resized(ANativeWindow* window);
			void on_native_window_redraw_needed(ANativeWindow* window);
			void on_window_focus_changed(int hasFocus);
			void on_native_window_destroyed(ANativeWindow* window);
			void on_input_queue_created(AInputQueue* queue);
			void on_input_queue_destroyed(AInputQueue* queue);
			void on_content_rect_changed(const ARect* rect);
			void* on_save_instance_state(size_t* outSize);
			void on_low_memory();
			void on_destroy();
			//virtual events
public:
			virtual void on_event_touch_move(const input::event::motion_event *event)=0;



public:
    virtual void render()=0;

public:
			virtual void activity_on_start()=0;
			virtual void activity_on_stop()=0;
			virtual void activity_on_resume()=0;
			virtual void activity_on_pause()=0;
			virtual void activity_before_destroy()=0;
			virtual void activity_on_destroy()=0;
			virtual void activity_on_window_created()=0;
			virtual void activity_on_configuration_changed()=0;
			virtual void activity_on_window_destroyed()=0;



private:
		void threading_init();
		void threading_lock_mutex();
		void threading_unlock_mutex();
		void threading_condition_wait();
		void threading_condition_broadcast();
private:
		void init_conf(AConfiguration *conf);

private:
	    void process_msg();
		void process_input();

private:
			and_config *current_config;
			messaging::messaging_abstract *current_messaging;

			    struct{
			    ANativeActivity * activity;
			    ANativeWindow *window;
			    }native;

			    struct{
			    	AInputQueue *queue;
			    }input;
			    struct
			    {
			    	ALooper *looper;
			    }poll;

			    struct {
			    pthread_mutex_t mutex;
			    pthread_cond_t condition;
			    pthread_t thread;

			    }threading;

			    struct{
			    	int state;
			    }status;
			    struct
			    {
			    	char *data;
			    	int len;
			    	int saved;

			    }saved_state;

			    struct{
			    	t_bool is_rendered_finished;
			    }rendering;
};

} /* namespace androidplus */
#endif /* ACTIVITY_H_ */
